package cn.yunyichina.provider.pay.service.impl;

import cn.yunyichina.provider.framework.dubbo.service.WechatPayService;
import cn.yunyichina.provider.iface.entity.common.ResponseObject;
import cn.yunyichina.provider.pay.constant.AppType;
import cn.yunyichina.provider.pay.constant.MethodRouter;
import cn.yunyichina.provider.pay.constant.ResponseEnum;
import cn.yunyichina.provider.pay.exception.PaySettingNotFoundException;
import cn.yunyichina.provider.pay.service.AuthConfigService;
import cn.yunyichina.provider.pay.service.BaseAuthConfigService;
import cn.yunyichina.utils.commons.RandomUtil;
import cn.yunyichina.utils.convert.JsonUtils;
import cn.yunyichina.utils.security.SignUtil;
import com.alibaba.fastjson.JSON;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by Lullaby on 2017/2/23.
 */
@Service
public class AuthConfigServiceImpl extends BaseAuthConfigService implements AuthConfigService {

    private static final Logger logger = LoggerFactory.getLogger(AuthConfigServiceImpl.class);

    public ResponseObject webAuthConfig(String data) {
        ResponseObject response = new ResponseObject();

        logger.info("AuthConfigServiceImpl.authConfig.data -> {}", data);

        try {
            Map<String, String> dataMap = JSON.parseObject(data, Map.class);

            String appType = dataMap.get("app_type");
            switch (AppType.valueOf(appType)) {
                case WECHAT:
                    response = getWechatWebAuthConfig(dataMap);
                    break;
                case ALIPAY:
                    response = getAlipayWebAuthConfig(dataMap);
                    break;
                default:
                    response.setResultCodeAndMessage(
                            ResponseEnum.UNKNOWN_APP_TYPE.getCode(),
                            ResponseEnum.UNKNOWN_APP_TYPE.getMessage()
                    );
                    break;
            }
        } catch (Exception e) {
            logger.error("AuthConfigServiceImpl.authConfig.exception", e);
            response.setResultCodeAndMessage(
                    ResponseEnum.WEB_AUTH_CONFIG_EXCEPTION.getCode(),
                    ResponseEnum.WEB_AUTH_CONFIG_EXCEPTION.getMessage()
            );
        }

        return response;
    }

    private ResponseObject getWechatWebAuthConfig(Map<String, String> params) throws PaySettingNotFoundException {
        ResponseObject response = new ResponseObject();

        if (checkWechatWebAuthConfigParameters(params)) {
            ResponseObject jsapiTicketResponse = WechatPayService.callUnderlineFromInternalObject(
                    MethodRouter.WECHAT_JSAPI_TICKET, JsonUtils.toJsonString(params)
            );

            logger.info("AuthConfigServiceImpl.getWechatWebAuthConfig.jsapiTicketResponse -> {}", JsonUtils.toJsonString(jsapiTicketResponse));

            if (jsapiTicketResponse.isSuccess()) {
                Map<String, String> jsapiTicketResult = JsonUtils.parseObject(jsapiTicketResponse.getResultObject(), Map.class);

                String jsapiTicket = jsapiTicketResult.get("ticket");

                String appid = params.get("app_id");
                String currentUrl = params.get("current_url");
                String timestamp = String.valueOf(Calendar.getInstance().getTimeInMillis() / 1000);
                String noncesStr = RandomUtil.getRandomALLChar(32);

                Map<String, String> signParamsMap = new HashMap<>();
                signParamsMap.put("jsapi_ticket", jsapiTicket);
                signParamsMap.put("noncestr", noncesStr);
                signParamsMap.put("timestamp", timestamp);
                signParamsMap.put("url", currentUrl);
                logger.info("AuthConfigServiceImpl.getWechatWebAuthConfig.signParamsMap -> {}", JsonUtils.toJsonString(signParamsMap));

                Map<String, String> resultMap = new HashMap<>();
                resultMap.put("app_id", appid);
                resultMap.put("timestamp", timestamp);
                resultMap.put("nonce_str", noncesStr);
                resultMap.put("signature", DigestUtils.sha1Hex(SignUtil.getWechatSignString(signParamsMap)));
                logger.info("AuthConfigServiceImpl.getWechatWebAuthConfig.resultMap -> {}", JsonUtils.toJsonString(resultMap));

                response.setResultObject(resultMap);
            } else {
                response.setResultCodeAndMessageAndResult(
                        jsapiTicketResponse.getResultCode(),
                        jsapiTicketResponse.getResultMessage(),
                        jsapiTicketResponse.getResultObject()
                );
            }
        } else {
            response.setResultCodeAndMessage(
                    ResponseEnum.Common.INVALID.getCode(),
                    ResponseEnum.Common.INVALID.getMessage()
            );
        }

        return response;
    }

    private ResponseObject getAlipayWebAuthConfig(Map<String, String> params) throws PaySettingNotFoundException {
        ResponseObject response = new ResponseObject();
        logger.info("AuthConfigServiceImpl.getAlipayWebAuthConfig.params", params);
        return response;
    }

}
